package com.ce.sys.main.action;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import net.sf.json.JSONArray;

import org.omg.CORBA.portable.ApplicationException;

import com.ce.framework.datamaintain.action.BaseAction;
import com.ce.framework.datamaintain.logic.IBaseLogic;
import com.ce.framework.datamaintain.logic.ISQLMapper;
import com.ce.framework.exception.AppException;
import com.ce.framework.util.StringUtil;
import com.ce.framework.util.node.JsonTreeNode;
import com.ce.sys.login.listener.LoginUserListener;
import com.ce.sys.login.model.User;
import com.ce.sys.menu.dao.po.SysMenu;
import com.ce.sys.menu.view.SysMenuView;
import com.ce.sys.org.view.OrgTreeNodeProperty;
import com.ce.util.RegeditUtil;

/**
 * 嫦娥软件有限公司 版权所有 2013
 * 创建人： andy
 * 创建时间： 2013-10-2 上午09:52:16
 * 功能描述： 打开系统主界面前进行的初始化信息的操作类
 * ==================================
 * 修改历史
 * 修改人        修改时间      修改位置（函数名）
 *
 * ==================================
 */
public class MainFrameAction extends BaseAction {
	private static final long serialVersionUID = 1L;
	
	/**
	 * 基本逻辑处理类
	 */
	protected IBaseLogic baselogic ; 
	
	public IBaseLogic getBaselogic() {
		return baselogic;
	}

	public void setBaselogic(IBaseLogic baselogic) {
		this.baselogic = baselogic;
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2013-10-2 上午09:53:59
	 * 功能描述：用于打开系统主界面的框架，同时加载必要的登录信息，菜单信息等操作
	 * 方法的参数和返回值
	 * @return
	 * @throws AppException
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	@SuppressWarnings({"deprecation" })
	public String enterMainFrame()throws AppException{
		List<?> projUrlList = this.getChildProjCreateSessionUserUrl(this.getRequest().getSession().getId());
		this.setAttribute("projUrlList", projUrlList);//建立子工程中session用户对象的地址
	    return "mainFramePage";//主框架界面
	}

	public String getAllUserJSON(){
		JSONArray ary = new JSONArray();
		String q = getParameter("q");
		String limit = getParameter("limit");
		if(StringUtil.isBlank(limit)){
			limit = "20";
		}
		String sql = "select * from (select p.vc_id,p.vc_name,o.VC_NAME as orgname from sys_t_person p ,sys_v_org$dep o where p.vc_org$id = o.VC_ID(+) and p.vc_id!='"+User.getUserId()+
		"'";
		if(StringUtil.isNotBlank(q)){
			sql += " and (p.vc_name like '%"+q+"%' or get_pinyin(p.vc_name) like '%"+q+"%')";
		}
		sql += " and p.vc_del$flag = 0 and p.vc_status = 1 order by p.vc_name) where rownum<"+limit;
		@SuppressWarnings("unchecked")
		List<String> list = (List<String>) this.baselogic.executeSQLQuery(sql, new ISQLMapper(){
			public Object fromSQLQuery(ResultSet rs, int num) {
				StringBuffer buff = new StringBuffer();
				try{
					buff.append(rs.getString("vc_id")).append("|");
					buff.append(rs.getString("vc_name")).append("|");
					buff.append(rs.getString("orgname")).append("|");				
				}catch(Exception e){
				   e.printStackTrace();
				}
				return buff.toString();
			}
			
		});
		String res = StringUtil.join(list.toArray(new String[list.size()]),"\n");
		ary.addAll(list);
		return writeHTML(res);
	}
	
	public String getOnlieUser(){
		JSONArray ary = new JSONArray();
		ary.addAll(LoginUserListener.getUserIdList());
		return writeHTML(ary.toString());
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： 2013-5-20 上午10:22:52
	 * 功能描述：获取子工程中建立session用户的地址信息
	 * 方法的参数和返回值
	 * @return
	 * List 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	private List<?> getChildProjCreateSessionUserUrl(String sid){
		List<String> projUrlList = new ArrayList<String>();
		if(StringUtil.isNotBlank(RegeditUtil.getRegeditStringValue(RegeditUtil.SESSION_CREATE_PROJECT_NAME))){
			String[] projNames = RegeditUtil.getRegeditStringValue(RegeditUtil.SESSION_CREATE_PROJECT_NAME).split(",");
			for(int i=0;i<projNames.length;i++){
				projUrlList.add("/"+projNames[i]+"/servlet/SessionCreateServlet");
			}
			   
		}
		return projUrlList;
	}
	
    /**
     * 开发人： andy
     * 开发时间： 2013-10-11 下午01:07:59
     * 功能描述： 构造当前登陆用户拥有的JSON格式的菜单树
     * 方法的参数和返回值
     * @throws ApplicationException
     * @throws AppException
     * void 
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
    public void searchUserMenuJsonTree()throws  AppException{
    	JSONArray jsonTree = new JSONArray();
    	List<?> menuList = new ArrayList<Object>();
    	String parId = this.getParameter("parId");
    	if(StringUtil.isBlank(this.getParameter("parId")))
    		throw new AppException("MenuTree's rootNode is not exit! ");
        //获取所有菜单
    	String allMenuSql = "select * from " +
    			"(select * from sys_t_menu t start with t.vc_par$id = '"+parId+"' connect by PRIOR t.vc_id = t.vc_par$id) " +
    					"where 1=1 and vc_del$flag=0 order by INT_SEQ ASC,VC_NAME Asc";
    	
    	//选取当前登录用户所在角色具有权限的菜单	   	
    	String curUserMenuSql = "select * from (select * from (select * from sys_t_menu m where m.vc_del$flag = 0 and (m.int_level = 1 or " +
    			"m.vc_id in (select p.vc_menu$id from sys_t_role$permiss p where p.vc_role$id = 'admin'))) start with vc_par$id = '"+parId+"' connect by PRIOR vc_id = vc_par$id) t " +
    			"where (t.int_level = 1 or (t.int_level = 0 and t.vc_id in (select p.vc_menu$id from sys_t_role$permiss p where p.vc_role$id = 'common' or p.vc_role$id in " +
    			"(select r.vc_role$id   from sys_t_account$role r where r.vc_user$id = '"+User.getUser().getVcId()+"')))) order by INT_SEQ ASC, VC_NAME Asc";

    	//选取当前登录用户所在角色具有权限的菜单,2012-04-15,本语句中未增加管理员权限过滤，暂不使用
//    	String curUserMenuSql = "select * from (" +
//    			"select *  from sys_t_menu m start with m.vc_par$id = '"+parId+"' connect by PRIOR m.vc_id = m.vc_par$id )t " +
//    			" where t.vc_del$flag = 0  and ( t.int_level = 1  or (t.int_level = 0 and  t.vc_id in " +
//    			"(select p.vc_menu$id from sys_t_role$permiss p where p.vc_role$id ='common' or p.vc_role$id in " +
//    			"(select r.vc_role$id from sys_t_account$role r  where r.vc_user$id = '"+User.getUser().getVcId()+"'))))" +
//    		    " order by INT_SEQ ASC,VC_NAME Asc";
    	if(User.getUser().isSuperUser())
    		curUserMenuSql = allMenuSql;
    	
    	//将通过SQL语句查询的结果集组合成SysMenuView对象的数组
    	menuList = this.baselogic.executeSQLQuery(curUserMenuSql.toString(),new ISQLMapper(){
			public SysMenu fromSQLQuery(ResultSet rs, int row) {
				SysMenuView view = new SysMenuView();
				try {
					view.setVcId(rs.getString("VC_ID"));
					view.setVcName(rs.getString("VC_NAME"));
					view.setIntLevel(rs.getInt("INT_LEVEL"));
					view.setIntSeq(rs.getInt("INT_SEQ"));
					view.setVcUrl(rs.getString("VC_URL"));
					view.setVcParId(rs.getString("VC_PAR$ID"));
					view.setVcMemo(rs.getString("VC_MEMO"));
					view.setVcIsMerge(rs.getInt("VC_IS$MERGE"));
					view.setVcLinkUrl(rs.getString("VC_LINK$URL"));
					view.setVcIconCls(rs.getString("vc_icon$cls"));
					view.setVcDelFlag(rs.getInt("VC_DEL$FLAG"));		
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return view;
			}
		});
		List<JsonTreeNode> childList = this.getChildNodeListForMenu(parId,
				menuList); // 获取根节点下的全部节点信息
		jsonTree.add(childList); // 写入树节点信息
		// 以字符串为文件流进行输出
		// 由于形成的json格式与easyui的格式在外部多了个[]，因此在这里进行移除。
		writeHTML(jsonTree.toString().substring(1, jsonTree.toString().length() - 1).toString()); // 将树以JSON格式的字符串进行输出

	}
    
    /**
     * 开发人： andy
     * 开发时间： 2013-10-11 下午01:08:18
     * 功能描述：获得子菜单树的JSON格式数据
     * 方法的参数和返回值
     * @param pid
     * @param menuList
     * @return
     * List 
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
    private List<JsonTreeNode> getChildNodeListForMenu(String pid,List<?> menuList){
    	return getChildNodeListForMenu(pid, menuList, 0);
    }
    private List<JsonTreeNode> getChildNodeListForMenu(String pid,List<?> menuList,int lvl){
    	List<JsonTreeNode> rootList = new ArrayList<JsonTreeNode>();
    	int openLvl = RegeditUtil.getRegeditIntValue("MAIN_MENU_OPEN_LEVEL",2);
    	//循环遍历所有机构
    	for(int i=0;i<menuList.size();i++){
    		SysMenuView menu = (SysMenuView)menuList.get(i);
    		//判断机构信息，当机构的上级ID和参数pid相同时，才将该机构纳入到子节点中
    		if(pid.equals(menu.getVcParId())){
        		JsonTreeNode child = new JsonTreeNode();
            	child.setId(menu.getVcId());
            	child.setText(menu.getVcName());
            	child.setIconCls(menu.getVcIconCls());
            	OrgTreeNodeProperty attr = new OrgTreeNodeProperty();
            	if(StringUtil.isNotBlank(menu.getVcUrl()))
            	    attr.setUrl(menu.getVcUrl());
            	attr.setOtherInfo(menu.getVcIsMerge().toString()); //子系统标志位
            	child.setAttributes(attr);
            	List<JsonTreeNode> childList = this.getChildNodeListForMenu(menu.getVcId(),menuList,lvl+1);  //递归获取的该节点的下级节点
            	child.setChildren(childList);
            	if(childList!=null&&childList.size()>0){  //当有子节点时默认树的状态为不展开
            	    child.setState(lvl<openLvl?"open":"closed");
            	    if(lvl>=openLvl){
                	    //child.setIconCls("ext-icon-book_open");
            	    }
            	}
            	//只将叶子节点及有子节点的节点存入
            	if(menu.getIntLevel()==0||(menu.getIntLevel()==1&&(childList!=null&&childList.size()>0)))
            	    rootList.add(child); //将节点放入List数组中
    		}
    	}
    	return rootList;
    }

    

    /**
     * 开发人： andy
     * 开发时间： 2013-11-5 下午04:48:41
     * 功能描述：将list中的user对象组成json格式字符串
     * 方法的参数和返回值
     * @param list
     * @return
     * String 
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
    private String getAllUserJson(List<?> list){
    	if(list==null||list.size()<=0)
    		return "[]";
		String json = new String("[");
		for(int i=0;i<list.size();i++){
			User user = (User)list.get(i);
			json = json + "{vcName:\""+user.getVcName()+"\",vcId:\""+user.getVcId()+"\",orgName:\""+user.getOrgName()+"\"},";
		}
		return json = json.substring(0,json.length()-1)+"]";
    }
    
    private List<?> getAllUser(){
		String sql = "select p.vc_id,p.vc_name,o.VC_NAME as orgname from sys_t_person p ,sys_v_org$dep o where p.vc_org$id = o.VC_ID(+) and p.vc_id!='"+User.getUserId()+"'  and p.vc_del$flag = 0 and p.vc_status = 1 order by p.vc_name";
		List<?> list = this.baselogic.executeSQLQuery(sql, new ISQLMapper(){
			public Object fromSQLQuery(ResultSet rs, int num) {
				// TODO Auto-generated method stub
				User user = new User();
				try{
					user.setVcId(rs.getString("vc_id"));
					user.setVcName(rs.getString("vc_name"));
					user.setOrgName(rs.getString("orgname"));					
				}catch(Exception e){
				   e.printStackTrace();
				}
				return user;
			}
			
		});
		return list;
    }
    
    /**
     * 开发人： andy
     * 开发时间： 2013-11-5 下午04:55:30
     * 功能描述： 获取不在线人员
     * 算法：将所有已登录人员的vcId组成字符串，然后用全部人员的vcId分别和该字符串进行对比，如果组成的字符串中包含该此vcId，就将该对象从全部人员中remove掉
     * 方法的参数和返回值
     * @param allUser
     * @param onLineUser
     * @return
     * List 
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
    private List<User> getAllOffLineUser(List<?> allUser,List<?> onLineUser){
    	List<User> offLineUser = new ArrayList<User>();
    	StringBuffer onLineUserIds = new StringBuffer("");
    	for(int i=0;i<onLineUser.size();i++){
    		User user = (User)onLineUser.get(i);
    		onLineUserIds.append(user.getVcId()+",");
    	}
    	Iterator<?> it = allUser.iterator();
    	while(it.hasNext()){
    		User user = (User)it.next();
    		if(onLineUserIds.toString().indexOf(user.getVcId())<0)
    			offLineUser.add(user);
    	}
    	return offLineUser;
    }
}
